package pack1_singleton;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 懒汉式单例模式：
 */
class Emperor2{
    private static Emperor2 emperor = null;
    private Emperor2(){};
    public static synchronized Emperor2 getInstance(){
        //同步代码块（emperor为空会报错）
//        synchronized(emperor){
//            if(emperor == null){
//                emperor = new Emperor2();
//            }
//            return emperor;
//        }
        if(emperor == null){
            emperor = new Emperor2();
        }
        return emperor;
    }
}

//内部类放在方法里面（放在public class之外，在执行futureTask会报错：java.lang.IncompatibleClassChangeError: Class Minister does not implement the requested interface java.util.concurrent.Callable）
class Minister2 implements Callable<Emperor2>{

    @Override
    public Emperor2 call() throws Exception {
        // TODO Auto-generated method stub
        Emperor2 emperor = Emperor2.getInstance();
        System.out.println("current_Thread = " + Thread.currentThread() + ",emperor = " + emperor);
        return emperor;
    }
}

public class code002_lazySingleton {

    public static void main(String[] args) {

        //开启线程池模拟多个minister线程访问emperor
        ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(10));
        int minister_count = 10;
        
        //不开线程池
        System.out.println("手动创建线程~~");
        for (int i = 0; i < minister_count; i++) {
            FutureTask<Emperor2> ft = new FutureTask<Emperor2>(new Minister2());
            Thread thread = new Thread(ft);
            thread.start();
            try {
                ft.get();
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch(InterruptedException e){
                e.printStackTrace();
            }   
        }
        
        //开线程池
        System.out.println("开启线程池~~");
        for (int i = 0; i < minister_count; i++) {
            FutureTask<Emperor2> ft = new FutureTask<Emperor2>(new Minister2());
            // executor.execute(ft);
            executor.submit(ft);
            try {
                ft.get();
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch(InterruptedException e){
                e.printStackTrace();
            }   
        }

        executor.shutdown(); //线程关闭
    }
}
